package com.mao.wx.demo.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.mao.wx.demo.constant.WxMessageConstant;
import com.mao.wx.demo.model.message.WxBasicMessage;
import com.mao.wx.demo.model.message.WxConfirmRequest;
import com.mao.wx.demo.model.message.WxImageMessage;
import com.mao.wx.demo.model.message.WxImageResponse;
import com.mao.wx.demo.model.message.WxLinkMessage;
import com.mao.wx.demo.model.message.WxLocationMessage;
import com.mao.wx.demo.model.message.WxTextMessage;
import com.mao.wx.demo.model.message.WxTextResponse;
import com.mao.wx.demo.model.message.WxVedioMessage;
import com.mao.wx.demo.model.message.WxVedioResponse;
import com.mao.wx.demo.model.message.WxVoiceMessage;
import com.mao.wx.demo.model.message.WxVoiceResponse;
import com.mao.wx.demo.util.WxEncryptUtil.WxEncryptAlgorim;
import com.thoughtworks.xstream.XStream;

@Component
@Qualifier(value = "wxMessageUtil")
public class WxMessageUtil {

	private static String wxToken = "maolala";
	private static String wxEncodingAESKey = "";

	/**
	 * 加密揭秘工具
	 */
	@Autowired(required = true)
	@Qualifier("wxEncryptUtil")
	private WxEncryptUtil wxEncryptUtil;

	/**
	 * Xml解析工具
	 */
	@Autowired(required = true)
	@Qualifier("wxXStrem")
	private XStream xStream;//可能由单利问题

	public WxMessageUtil() {

	}

	/**
	 * 用于第一次与微信后台确认连接时的签名认真
	 * 
	 * @param request
	 * @return
	 */
	public String getConfirmSignature(WxConfirmRequest request) {
		String[] list = new String[] { wxToken, request.getTimestamp(), request.getNonce() };
		Arrays.sort(list);
		StringBuffer strBuffer = new StringBuffer();
		for (int i = 0; i < list.length; i++) {
			strBuffer.append(list[i]);
		}
		String content = strBuffer.toString();
		try {
			String signature = this.wxEncryptUtil.getSha1(content);
			return signature;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获得消息签名
	 * 
	 * @param args
	 * @return
	 */
	public String getMessageSignature(String[] args, WxEncryptAlgorim encrypt) {

		return null;
	}

	/**
	 * 将腾讯的XML消息转成Map
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> parseXmlToMap(HttpServletRequest request) throws Exception {
		SAXReader xmlReader = new SAXReader();
		InputStream is = request.getInputStream();
		Document document = xmlReader.read(is);
		Element rootElement = document.getRootElement();
		if (!"xml".equals(rootElement.getName())) {
			throw new RuntimeException("Wrong xml format request!");
		}
		Map<String, String> results = new HashMap<String, String>();
		List<Element> elements = rootElement.elements();
		for (Element e : elements) {
			results.put(e.getName(), e.getText());
		}
		is.close();
		xmlReader = null;
		return results;
	}

	/**
	 * 将Map数据专程成3个对象的map Map["MsgType","RequestMsg","ResponseMsg"]
	 * 
	 * @param map
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> parseMapToObj(Map<String, String> map) throws Exception {

		Map<String, Object> results = new HashMap<>();
		String type = map.get("MsgType");
		if (type == null) {
			throw new RuntimeException("Erroe xml request format!");
		}
		results.put("MsgType", type);
		WxBasicMessage requestMsg = null;
		WxBasicMessage responseMsg = null;
		try {
			if (type.equals(WxMessageConstant.XML_MSG_TEXT)) {
				requestMsg = new WxTextMessage(map);
				responseMsg = new WxTextResponse(map);
			} else if (type.equals(WxMessageConstant.XML_MSG_IMAGE)) {
				requestMsg = new WxImageMessage(map);
				responseMsg = new WxImageResponse(map);
			} else if (type.equals(WxMessageConstant.XML_MSG_LOCATION)) {
				requestMsg=new WxLocationMessage(map);

			} else if (type.equals(WxMessageConstant.XML_MSG_MUSIC)) {

			} else if (type.equals(WxMessageConstant.XML_MSG_VOICE)) {
				requestMsg=new WxVoiceMessage(map);
				responseMsg=new WxVoiceResponse(map);
			}else if(type.equals(WxMessageConstant.XML_MSG_VIDEO)){
				requestMsg=new WxVedioMessage(map);
				responseMsg=new WxVedioResponse(map);
			}else if(type.equals(WxMessageConstant.XML_MSG_LINK)){
				requestMsg=new WxLinkMessage(map);
			}
			results.put("RequestMsg", requestMsg);
			results.put("ResponseMsg", responseMsg);
			return results;
		} catch (Exception e) {
			throw new RuntimeException("Erroe xml request format!");
		}
	}

	public String getXmlResponse(Object response, Class clazz) {
		xStream.alias("xml", clazz);
		String xml = xStream.toXML(response);
		return xml;
	}
}
